use axum::{
    body::Body,
    extract::{Path, Query, State},
    http::{Response, StatusCode},
    response::IntoResponse,
    Json,
};
use sky_common::constant;
use sky_pojo::{
    dto::{
        enable_disable,
        setmeal::{DeleteSetmealBarnch, SetMealQueryDTO, SetmealDTO},
    },
    entities::setmeal::Model,
    vo::{setmeal::SetmealVO, PageResult},
};

use crate::{bootstrap::AppState, middleware::jwt::admin::Claims, router::resp::RespVO, service};

pub async fn create(
    _claim: Claims,
    State(state): State<AppState>,
    Json(dto): Json<SetmealDTO>,
) -> Response<Body> {
    match service::setmeal::save_with_dishes(state.db_pool, dto, _claim.id).await {
        Ok(meal_id) => RespVO::<i64>::success("success".to_owned(), Some(meal_id)).into_response(),
        Err(e) => RespVO::<()>::error_without_data(e).into_response(),
    }
}
pub async fn query(
    _claim: Claims,
    State(state): State<AppState>,
    Query(dto): Query<SetMealQueryDTO>,
) -> Response<Body> {
    match service::setmeal::query(state.db_pool, dto).await {
        Ok(pages) => {
            RespVO::<PageResult<Model>>::success("success".to_owned(), Some(pages)).into_response()
        }
        Err(e) => RespVO::<()>::error_without_data(e.to_string()).into_response(),
    }
}

pub async fn modify(
    claim: Claims,
    State(state): State<AppState>,
    Json(dto): Json<SetmealDTO>,
) -> Response<Body> {
    match service::setmeal::modify_widh_dishes(state.db_pool, dto, claim.id).await {
        Ok(vo) => RespVO::<SetmealVO>::success("success".to_owned(), Some(vo)).into_response(),
        Err(e) => RespVO::<()>::error_without_data(e).into_response(),
    }
}

pub async fn enable_disable(
    claim: Claims,
    State(state): State<AppState>,
    Path(status): Path<i32>,
    Query(query): Query<enable_disable::EDQuery>,
) -> Response<Body> {
    let mut dto = SetmealDTO::new();
    dto.id = Some(query.id);
    dto.status = Some(status);
    match service::setmeal::enable_disable(state.db_pool, dto, claim.id).await {
        Ok(model) => {
            RespVO::<SetmealVO>::success("success".to_owned(), Some(model)).into_response()
        }
        Err(e) => {
            RespVO::<()>::error_without_data(constant::message::SETMEAL_ENABLE_FAILED.to_owned())
                .into_response()
        }
    }
}

pub async fn delete_setmeal_barnch(
    _claim: Claims,
    State(state): State<AppState>,
    Query(query): Query<DeleteSetmealBarnch>,
) -> Response<Body> {
    let res = service::setmeal::delete_branch(state.db_pool, query.ids).await;

    RespVO::from_result(
        Some(StatusCode::ACCEPTED.as_u16()),
        Some("".to_owned()),
        Some(res),
    )
    .into_response()
}

pub async fn query_by_id(
    _claim: Claims,
    State(state): State<AppState>,
    Path(id): Path<i64>,
) -> Response<Body> {
    match service::setmeal::query_by_id(state.db_pool, id).await {
        Ok(res) => RespVO::<SetmealVO>::success("success".to_owned(), Some(res)).into_response(),
        Err(e) => RespVO::<()>::error_without_data(e).into_response(),
    }
}
